home *** CD-ROM | disk | FTP | other *** search
/ Delphi Magazine Collection 2001 / Delphi Magazine Collection 20001 (2001).iso / DISKS / ISSUE08 / INTERNAL / FORMAT.PAS
Encoding:
Pascal/Delphi Source File  |  1996-03-05  |  6.9 KB  |  191 lines

  1. unit Format;
  2.  
  3. interface
  4.  
  5. uses WinTypes, WinProcs;
  6.  
  7. const
  8.     { Format capacities }
  9.     DF_360K     =       0;
  10.     DF_12M      =       1;
  11.     DF_720K     =       2;
  12.     DF_14M      =       3;
  13.     DF_28M      =       4;
  14.     DF_Unknown  =       5;
  15.  
  16. function AbsRead (Drive: Byte; NumSectors, StartSec: Integer;
  17.                   Buffer: Pointer): Integer;
  18. function AbsWrite (Drive: Byte; NumSectors, StartSec: Integer;
  19.                   Buffer: Pointer): Integer;
  20. function GetMediaType (Drive: Byte): Integer;
  21. function LockVolume (Drive: Byte): Integer;
  22. function UnLockVolume (Drive: Byte): Integer;
  23.  
  24. implementation
  25.  
  26. type
  27.     DiskType = record
  28.         spc: Byte;              { sectors per cluster }
  29.         rde: Integer;           { number of root-dir entries }
  30.         sec: Integer;           { total number of sectors }
  31.         med: Byte;              { media descriptor }
  32.         spf: Integer;           { number of sectors per FAT }
  33.         spt: Integer;           { sectors per track }
  34.     end;
  35.  
  36. const
  37.     { This array maps a logical drive type to a list of     }
  38.     { parameters for that drive.  Assumptions:              }
  39.     { Bytes per sector = 512  Reserved sectors = 1          }
  40.     { Number of FATS = 2      Heads = 2                     }
  41.     { Hidden sectors = 0      Tracks = 80 except 40 for 1st }
  42.  
  43.     DiskTypes: array [0..4] of DiskType = (
  44.  
  45.     (spc:2; rde:112; sec: 720; med:$FD; spf:2; spt: 9),   { 360 K }
  46.     (spc:1; rde:224; sec:2400; med:$F9; spf:7; spt:15),   { 1.2 M }
  47.     (spc:2; rde:112; sec:1440; med:$F9; spf:3; spt: 9),   { 720 K }
  48.     (spc:1; rde:224; sec:2880; med:$F0; spf:9; spt:18),   { 1.4 M }
  49.     (spc:2; rde:240; sec:5760; med:$F0; spf:9; spt:36));  { 2.8 M }
  50.  
  51. type
  52.     PBootSector = ^BootSector;
  53.     BootSector = record
  54.     bsJump: array [0..2] of Byte;        { 00 E9 XX XX or EB XX 90 }
  55.     bsOemName: array [0..7] of Char;        { 03 OEM name and version }
  56.     bsBytesPerSec: Integer;            { 0b bytes per sector }
  57.         bsSecPerClust: Byte;            { 0d sectors per cluster }
  58.         bsResSectors: Integer;            { 0e number of reserved sectors }
  59.         bsFATs: Byte;                { 10 number of file allocation tables }
  60.         bsRootDirEnts: Integer;            { 11 number of root-directory entries }
  61.     bsSectors: Integer;                    { 13 total number of sectors }
  62.         bsMedia: Byte;                    { 15 media descriptor }
  63.         bsFATsecs: Integer;                    { 16 number of sectors per FAT }
  64.         bsSecPerTrack: Integer;                { 18 sectors per track }
  65.         bsHeads: Integer;                    { 1a number of heads }
  66.         bsHiddenSecs: LongInt;                 { 1c number of hidden sectors }
  67.         bsHugeSectors: LongInt;                { 20 number of sectors if bsSectors = 0 }
  68.         bsDriveNumber: Byte;                { 24 drive number }
  69.         bsReserved1: Byte;                    { 25 reserved }
  70.         bsBootSignature: Byte;                { 26 extended boot signature }
  71.         bsVolumeID: LongInt;                { 27 volume ID number }
  72.         bsVolumeLabel: array [0..10] of Char;    { 2b volume label }
  73.         bsFileSysType: array [0..7] of Char;    { 36 file-system type }
  74.     end;
  75.  
  76. { Determine if we're running Windows 95 (or later) }
  77.  
  78. function IsWindows95: Bool;
  79. var
  80.     ver: LongInt;
  81.     v: array [0..1] of Word absolute ver;
  82. begin
  83.     ver := GetVersion;
  84.     IsWindows95 := (Swap (v[0]) >= $35F) and (v[1] >= $700);
  85. end;
  86.  
  87. { Read an absolute sector from a specified drive }
  88.  
  89. function AbsRead (Drive: Byte; NumSectors, StartSec: Integer;
  90.                   Buffer: Pointer): Integer; assembler;
  91. asm
  92.     mov        al,Drive            { AL = drive number for read  }
  93.     dec     al                          { for compatability, A=1,...  }
  94.     mov        cx,NumSectors        { number of sectors to read   }
  95.     mov        dx,StartSec            { first sector to read          }
  96.     push    ds                { save DS prior to call          }
  97.     lds        bx,Buffer            { DS:BX = pointer to buffer   }
  98.     push    bp                { save stack frame          }
  99.     int        25h                { do the absolute read          }
  100.     pop     bx                { pop and discard flags          }
  101.     pop     bp                { restore stack frame          }
  102.     pop        ds                { restore DS register          }
  103.     jc        @@1                { branch if error          }
  104.     xor        ax,ax            { no error - return zero      }
  105. @@1:
  106. end;
  107.  
  108. { Write an absolute sector to a specified drive }
  109.  
  110. function AbsWrite (Drive: Byte; NumSectors, StartSec: Integer;
  111.                    Buffer: Pointer): Integer; assembler;
  112. asm
  113.     mov        al,Drive            { AL = drive number for write }
  114.     dec     al                          { for compatability, A=1,...  }
  115.     mov        cx,NumSectors        { number of sectors to write  }
  116.     mov        dx,StartSec            { first sector to write          }
  117.     push    ds                { save DS prior to call          }
  118.     lds        bx,Buffer            { DS:BX = pointer to buffer   }
  119.     push    bp                { save stack frame          }
  120.     int        26h                { do the absolute write          }
  121.     pop     bx                { pop and discard flags          }
  122.     pop     bp                { restore stack frame          }
  123.     pop        ds                { restore DS register          }
  124.     jc        @@1                { branch if error          }
  125.     xor        ax,ax            { no error - return zero      }
  126. @@1:
  127. end;
  128.  
  129. { Return the type of a given drive }
  130.  
  131. function GetMediaType (Drive: Byte): Integer;
  132. var
  133.     i: Integer;
  134.     buff: array [0..511] of Byte;
  135.     bs: BootSector absolute buff;
  136. begin
  137.     GetMediaType := -1;
  138.     { Read boot sector from disk }
  139.     if AbsRead (Drive, 1, 0, @buff) = 0 then
  140.     begin
  141.         GetMediaType := DF_Unknown;
  142.         for i := DF_360K to DF_28M do
  143.             if bs.bsSectors = DiskTypes [i].sec then
  144.             begin
  145.                 GetMediaType := i;
  146.                 Exit;
  147.             end;
  148.     end;
  149. end;
  150.  
  151. function LUVolumePrim (Drive, Level, Op: Byte; Perm: Word): Integer; assembler;
  152. asm
  153.     mov     ax,$440D        { specify generic IOCTL call }
  154.     mov     bl,Drive        { get drive number in BL     }
  155.     dec     bl              { for compatability, A: = 1  }
  156.     mov     bh,Level        { get lock level in BH       }
  157.     mov     ch,8            { category 8 for drives      }
  158.     mov     cl,Op           { get lock/unlock physical   }
  159.     mov     dx,Perm         { get permissions word       }
  160.     int     21h             { make the call              }
  161.     jc      @@1             { branch if error            }
  162.     xor     ax,ax           { no error - so AX = 0       }
  163. @@1:
  164. end;
  165.  
  166. function LockVolume (Drive: Byte): Integer;
  167. begin
  168.     if IsWindows95 then
  169.     begin
  170.         LockVolume := -1;
  171.         if LUVolumePrim (Drive, 0, $4B, 0) = 0 then
  172.             if LUVolumePrim (Drive, 0, $4B, 4) = 0 then
  173.                 LockVolume := 0;
  174.     end
  175.     else LockVolume := 0;
  176. end;
  177.  
  178. function UnLockVolume (Drive: Byte): Integer;
  179. begin
  180.     if IsWindows95 then
  181.     begin
  182.         UnLockVolume := -1;
  183.          if LUVolumePrim (Drive, 0, $6B, 0) = 0 then
  184.             if LUVolumePrim (Drive, 0, $6B, 0) = 0 then
  185.                 UnLockVolume := 0;
  186.     end
  187.     else UnLockVolume := 0;
  188. end;
  189.  
  190. end.
  191.